<?php
defined( 'BASEPATH' ) or exit( 'No direct script access allowed' );

class JsonResult
{
    private $_config = array (
            'debug' => false,
            'callback' => '' 
    );
    /**
     * 建议在URL入口处开启ob_start()，
     * 一来可以防止设置header时报错，二来可以全面捕捉输出内容
     *
     * @param array $config            
     */
    function __construct($config = array())
    {
        if (is_array( $config ))
        {
            foreach ( $config as $k => $v )
            {
                $k = strtolower( $k );
                if (isset( $this->_config[$k] ))
                {
                    $this->_config[$k] = $v;
                }
            }
        }
    }
    function ok($data = null, $data_value = null)
    {
        $rs = array ();
        $rs['err'] = 0;
        $rs['data'] = $data_value === null ? $data : array (
                $data => $data_value 
        );
        $this->output( $rs );
    }
    /**
     * 业务错误
     *
     * @param unknown $err            
     */
    function err($err = 1)
    {
        $rs = array ();
        if (is_numeric( $err ))
        {
            // 标准错误，仅需提供错误码
            $rs['err'] = $err;
            $rs['msg'] = ResultError::getText( $err );
        }
        else
        {
            // 其他非标准错误，错误号统一为：-1，错误内容由具体逻辑提供。
            $rs['err'] = - 1;
            $rs['msg'] = $err;
        }
        $this->output( $rs );
    }
    function output($obj)
    {
        // 缓冲处理
        for($level = ob_get_level(); $level > 1; -- $level)
        {
            ob_end_flush();
        }
        $out = ob_get_contents();
        // 如果没有手动开启缓冲，而系统默认缓冲区只有1K，有可能因为输出大于1K造成实际输出，从而清理不干净。
        ob_clean();
        
        // 输出
        $rs_str = json_encode( $obj, JSON_UNESCAPED_UNICODE );
        if (! empty( $this->_config['callback'] ))
        {
            header( "content-type:text/javascript;charset=utf-8" );
            if (! preg_match( "/^[\w_]+$/", $this->_config['callback'] ))
            {
                echo 'alert("callback参数不合法");';
                exit();
            }
            $rs_str = $this->_config['callback'] . "($rs_str);";
        }
        elseif ($this->_config['debug'])
        {
            header( "content-type:text/html;charset=utf-8" );
            // header( "content-type:text/plain;charset=utf-8" );
        }
        else
        {
            header( "content-type:application/json;charset=utf-8" );
        }
        
        if ($this->_config['debug'])
        {
            echo $out;
        }
        echo $rs_str;
        exit();
    }
}
/**
 * 标准的业务错误码定义
 */
class ResultError
{
    private static $code = array (
            '1' => '系统错误', // 非预期错误
            '2' => '参数错误',
            '3' => '未登陆',
            '4' => '无访问权限',
            // 所请求数据要求非空的情况下，而服务器没有数据，此时应报错。
            // 如果客户端预期了空结果，此时无需报错，直接返回空结果即可。
            '5' => '没有数据' 
    );
    public static function getText($errno)
    {
        if (isset( self::$code[$errno] ))
        {
            return self::$code[$errno];
        }
        else
        {
            return '未定义的错误号';
        }
    }
}